package cn.xiaobai.loader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * @Author yangdaji
 * @Date 2023/10/27
 * @PackageName cn.xiaobai.loader
 * @ClassName Tt
 */
public class JarClassLoader extends ClassLoader {


    private JarFile jarFile;

    private ClassLoader parent;

    private String className;

    public JarClassLoader(JarFile jarFile) {
        super(Thread.currentThread().getContextClassLoader());
        this.parent = Thread.currentThread().getContextClassLoader();
        this.jarFile = jarFile;
    }

    public JarClassLoader(JarFile jarFile, String className) {
        super(Thread.currentThread().getContextClassLoader());
        this.parent = Thread.currentThread().getContextClassLoader();
        this.jarFile = jarFile;
        this.className = className;
    }

    public JarClassLoader(JarFile jarFile, ClassLoader parent) {
        super(parent);
        this.parent = parent;
        this.jarFile = jarFile;
    }

//    private byte[] loadByte() throws Exception {
//        byte[] data = new byte[inputStream.available()];
//        try {
//            inputStream.read(data);
//        }finally {
////            inputStream.close();
//        }
//        return data;
//    }

//    @Override
//    protected Class<?> findClass(String name) throws ClassNotFoundException {
//        try {
//            byte[] data = loadByte();
//            return defineClass(name, data, 0, data.length);
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new ClassNotFoundException();
//        }
//    }

//    public static void main(String[] args) throws Exception {
//        String path = "C:\\Users\\dell\\Desktop\\xiaobai\\plugin-demo\\target\\plugin-demo-0.0.1-SNAPSHOT.jar";
//        String name = "BOOT-INF/classes/cn/xiaobai/plugindemo/PluginDemoApplication.class";
//        File file = new File(path);
//        JarFile jarFile1 = new JarFile(file);
//        JarClassLoader jarClassLoader = new JarClassLoader(jarFile1);
//        Class<?> aClass = jarClassLoader.findClass(name);
//    }

    protected Class<?> findClass(String entryName, String className) throws ClassNotFoundException {
        this.className = className;
        return findClass(entryName);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            Class c = null;
            if (null != jarFile) {
                JarEntry entry = jarFile.getJarEntry(name);
                if (null != entry) {
                    InputStream is = jarFile.getInputStream(entry);
                    int availableLen = is.available();
                    int len = 0;
                    byte[] data = new byte[availableLen];
                    while (len < availableLen) {
                        len += is.read(data, len, availableLen - len);
                    }
                    c = defineClass(className, data, 0, data.length);
                } else {
                    if (parent != null) {
                        return parent.loadClass(name);
                    }
                }
            }
            return c;
        } catch (IOException e) {
            throw new ClassNotFoundException("Class " + name + " not found.");
        }
    }
}
